package com.mx.tool.form.window.zh;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mx.tool.util.NotifyUtil;
import org.apache.commons.lang3.StringUtils;

import javax.swing.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 徐建鹏.
 * @create: 2021-11-10 14:55
 * @Description:
 */
public class JsonToEntityWindow {

    private JPanel jPanel;
    private JTextArea contentArea;
    private JTextArea showArea;
    private JTextField packageText;
    private JTextField classNameText;
    private JButton button;

    public JsonToEntityWindow() {
        button.addActionListener(e -> {
            showArea.setText("");
            String jsonStr = contentArea.getText();
            if (StringUtils.isBlank(jsonStr)) {
                NotifyUtil.error("请输入json字符串");
                return;
            }
            String className = StringUtils.defaultIfBlank(classNameText.getText(), "ClassName");
            try {
                showArea.setText(createBean(className, JSON.parse(jsonStr)));
            }catch (Exception ex){
                ex.printStackTrace();
                NotifyUtil.error("json解析失败");
            }
        });
    }

    private String createBean(String className, Object jsonObject) {
        String packageName = StringUtils.defaultIfBlank(packageText.getText(), "packages");
        if (jsonObject instanceof List) {
            jsonObject = ((List<?>) jsonObject).get(0);
        }
        StringBuilder beanBuilder = new StringBuilder();
        StringBuilder importBuilder = new StringBuilder("package ").append(packageName).append(";");
        StringBuilder attrBuilder = new StringBuilder();
        StringBuilder methodBuilder = new StringBuilder();
        Map<String, String> childClass = new HashMap<>();
        for (Map.Entry<String, Object> entry : ((JSONObject) jsonObject).entrySet()) {
            Object value = entry.getValue();
            String key = StrUtil.toCamelCase(entry.getKey());
            String keyName = StrUtil.upperFirst(key);
            if (value instanceof String) {
                attrBuilder.append("\n\tprivate String ").append(key).append(";");
                methodBuilder.append("\n\tpublic String get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(String ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
            } else if (value instanceof Integer) {
                attrBuilder.append("\n\tprivate Integer ").append(key).append(";");
                methodBuilder.append("\n\tpublic Integer get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(Integer ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
            } else if (value instanceof BigDecimal) {
                attrBuilder.append("\n\tprivate Double ").append(key).append(";");
                methodBuilder.append("\n\tpublic Double get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(Double ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
            } else if (value instanceof BigInteger || value instanceof Long) {
                attrBuilder.append("\n\tprivate Long ").append(key).append(";");
                methodBuilder.append("\n\tpublic Long get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(Long ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
            } else if (value instanceof List) {
                attrBuilder.append("\n\tprivate List<").append(keyName).append("> ").append(key).append(";");
                importBuilder.append("\nimport java.util.List;");
                methodBuilder.append("\n\tpublic List<").append(keyName).append("> ").append("get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(List<").append(keyName).append("> ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
                String subclassString = createBean(keyName, value);
                childClass.put(keyName, subclassString);
            } else if (value instanceof Map) {
                attrBuilder.append("\n\tprivate ").append(keyName).append(" ").append(key).append(";");
                String subclassString = createBean(keyName, value);
                childClass.put(keyName, subclassString);
                methodBuilder.append("\n\tpublic ").append(keyName).append(" get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(").append(keyName).append(" ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
            } else {
                attrBuilder.append("\n\tprivate String ").append(key).append(";");
                methodBuilder.append("\n\tpublic String get").append(keyName).append("(){\n\t\treturn this.").append(key).append(";\n\t}");
                methodBuilder.append("\n\tpublic void set").append(keyName).append("(String ").append(key).append("){\n\t\tthis.").append(key).append(" = ").append(key).append(";\n\t}");
            }
        }
        beanBuilder.append(importBuilder);
        beanBuilder.append("\npublic class ").append(className).append("\n{");
        beanBuilder.append(attrBuilder);
        beanBuilder.append("\n").append(methodBuilder);
        beanBuilder.append("\n}");
        childClass.forEach((key, value) -> {
            beanBuilder.append("\n\n============").append(key).append("类=================\n");
            beanBuilder.append(value);
        });
        return beanBuilder.toString();
    }

    public JPanel getContent() {
        return jPanel;
    }


}
